package com.shanxia.codec.cmd;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.enums.DecodeEnum;
import com.shanxia.codec.enums.ModuleWarningEnum;
import com.shanxia.codec.enums.SystemWarningEnum;
import lombok.Data;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static com.shanxia.codec.CodeConstant.TENTH;
import static com.shanxia.codec.Decoder.*;

/**
 * C -> S
 * 充电桩模块信息上报
 * 充电桩模块信息
 */
@Data
public class Cmd112 extends ProtocolDataBase {

    public static final int MIN_SIZE = 39;

    private int v1;
    private int v2;
    private String sn;                        // 充电桩编码
    private int reportWay;                    // 上报方式
    private int moduleCount;                  // 模块数量
    private int moduleType;                   // 模块类型
    private List<Module> modules;             // 模块

    public Cmd112(){
        super.setCmd(112);
    }

    public static Cmd112 decodeFromBase(ProtocolDataBase protocolDataBase) {
        Cmd112 cmd = new Cmd112();
        cmd.copyDataFrom(protocolDataBase);
        byte[] dataField = protocolDataBase.getDataField();
        if (dataField.length < MIN_SIZE) {
            cmd.setResult(DecodeEnum.InvalidData);
            return cmd;
        }
        int offset = 0;
        cmd.v1 = getUint16(dataField, offset);
        offset += 2;
        cmd.v2 = getUint16(dataField, offset);
        offset += 2;
        // 32字节充电桩编码
        cmd.sn = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 32), true);
        offset += 32;
        // 1字节上报方式
        cmd.reportWay = getUint8(dataField[offset++]);
        // 1字节模块数量
        cmd.moduleCount = getUint8(dataField[offset++]);
        // 1字节模块类型
        cmd.moduleType = getUint8(dataField[offset++]);
        // N个模块数量
        List<Module> modules = new ArrayList<>();
        Module module;
        for (int i = 0; i < cmd.moduleCount; i ++) {
            module = new Module();
            // 2字节AC版本
            module.acVersion = getUint16(dataField, offset);
            offset += 2;
            // 2字节DC版本
            module.dcVersion = getUint16(dataField, offset);
            offset += 2;
            // 1字节状态
            module.status = getUint8(dataField[offset++]);
            // 2字节输出电压
            module.voltage = new BigDecimal(getUint16(dataField, offset)).multiply(TENTH).doubleValue();
            offset += 2;
            // 2字节输出电流
            module.current = new BigDecimal(getUint16(dataField, offset)).multiply(TENTH).doubleValue();
            offset += 2;
            // 4字节告警
            List<ModuleWarningEnum> warnings = new ArrayList<>(16);
            for (int j = 0; j < 4; j ++) {
                byte value = dataField[offset++];
                for (int b = 0; b < 8; b ++) {
                    if (Objects.equals(getBits(value, b, 1), 1)) {
                        warnings.add(ModuleWarningEnum.getByPos(j, b));
                    }
                }
            }
            modules.add(module);
        }
        return cmd;
    }

    public static class Module {
        private int acVersion;                          // AC版本
        private int dcVersion;                          // DC版本
        private int status;                             // 状态
        private double voltage;                         // 输出电压
        private double current;                         // 输出电流
        private List<ModuleWarningEnum> warnings;       // 告警
    }

    @Override
    public String toString() {

        StringBuffer buffer = new StringBuffer();
        buffer.append("#cmd112#").append("\n");
        buffer.append("v1:").append(v1).append("\n");
        buffer.append("v2:").append(v2).append("\n");
        buffer.append("充电桩编码:").append(sn).append("\n");
        buffer.append("上报方式:").append(reportWay).append("\n");
        buffer.append("模块数量:").append(moduleCount).append("\n");
        buffer.append("模块类型:").append(moduleType).append("\n");
        buffer.append("模块:【").append("\n");
        for(Module module : modules){
            buffer.append("AC版本:").append(module.acVersion).append("\n");
            buffer.append("DC版本:").append(module.dcVersion).append("\n");
            buffer.append("状态:").append(module.status).append("\n");
            buffer.append("输出电压:").append(module.voltage).append("\n");
            buffer.append("输出电流:").append(module.current).append("\n");
            buffer.append("告警:{").append("\n");
            for(ModuleWarningEnum warningEnum : module.warnings){
                buffer.append(warningEnum.descr).append("\n");
            }
            buffer.append("}").append("\n");
        }
        buffer.append("】").append("\n");
        return buffer.toString();
    }
}
